Key:
Save
Speagram Home
|
tutorial
|
use me
|
live interface
|
documentation
|
developer's corner
|
links
|
contact
TUTORIAL EXAMPLE: SYMBOLIC DIFFERENTIATION
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
TEMPLAT_TEXT
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
On this page of our tutorial we present a program which shows you how to define structurally complex classes and how to define specialized functions to deal with such complex classes. In other words, we will define a grammar (and a parser at the same time) and transformations acting on the elements belonging to this grammar. We will define the class %PexpressionP% (= a polynomial with natural coefficients here), the function ' to symbolically calculate the derivative of any such expression, and finally the function %PsimplifyP% to reduce expressions into simple form. We will focus on assigning priority and binding rules so that the user can write with as few brackets as possible. After all, it is the parser's job to see brackets where they are implicitly intended. We will be going through the example program part by part. At the end of this page you will find the whole program in one piece. We will assume that you are already acquainted with the [[Tutorial Example: Simple English Syntax Parser.php|English syntax parser]] example.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Let's begin. %$ Load state library:/basic. New class ''expression''. Variable d as expression. Variable e as expression. Variable f as expression. Variable n as natural number. $% These lines introduce temporary variables which will be used in the declarations that follow. These variables will exist until %PClose contextP%. is used.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
%$ New element natural number as expression. See last element as cast. New element ''x'' as expression. $% Here we inform the parser that we want to treat every natural number as memeber of the %PexpressionP% class. Additionally, we introduce a new element %PxP% as a member of this class. Recall that a natural number will be perceived as an expression only when necessary (thanks to %PSee last element as cast.P%).
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Run to see for yourself: %$x. 7.$%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Let's go on with the program. %$ New element expression ''+'' expression as expression. See (d+e)+f preferred to d+(e+f). $% This declaration introduces a new element into the class expression. Namely, the sum of two expressions. Notice that we use empahis (double apostrophes ('') in edit mode) around the plus operator. Notice how we deal with associativity. We inform the parser that d+e+f should be parsed as (d+e)+f rather than d+(e+f). Now we can safely write 1+2+x without worrying about ambiguity.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
The following declarations are similar. Notice how we deal with the fact that multiplication binds stronger than addition and that exponentiation binds stronger than multiplication. %$ New element expression ''*'' expression as expression. See (d*e)*f preferred to d*(e*f). See (d*e)+f preferred to d*(e+f). See d+(e*f) preferred to (d+e)*f. New element expression ''^'' natural number as expression. See d+(e^n) preferred to (d+e)^n. See d*(e^n) preferred to (d*e)^n. Close context. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Without specifying these preferences we would have to write 2+(3*3) instead of the usual 2+3*3 in order to avoid ambiguity. As it is now, we are done with the definition of our class and we can use it comfortably. Run to see it yourself: %$ 9+x. x+2*x. x^9. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Now that the class expression is ready to use, we are going to define a differentiating function which transforms an expression into an expression which is the symbolically calculated derivative of the original expression. The name of the function will be ' (yes, it's the prime). It is one of Speagram's charms that it allows such function names. (The name for the factorial function can be ! so that n! is a proper usage of this function.) Take a look at the whole definition of the function before we define it in a stepwise manner. %P New function expression '' ' '' as expression. Variable n as natural number. Variable e as expression. Variable d as expression. See e + (d') preferred to (e+d)'. See (e') + d preferred to (e+d)'. See e * (d') preferred to (e*d)'. See (e') * d preferred to (e*d)'. Let n' be 0. Let x' be 1. Let (d + e)' be d' + e'. Let (d * e)' be d' * e + d * e'. Let (e ^ 0)' be 0. Let (e ^ n)' be n * e ^ (n-1) * e'. Close context. P%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
The first line %$ New function expression '' ' '' as expression. $% simply states that an expression followed by the prime symbol is still an expression. This is analogous to introducing the name for the function, declaring what arguments it takes and of what type they are, and finally stating the return type.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
The next three lines %$ Variable n as natural number. Variable e as expression. Variable d as expression. $% introduce temporary variables which will be used in the function definition. These variables will exist until %PClose context.P% is used.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
The next four lines %$ See e + (d') preferred to (e+d)'. See (e') + d preferred to (e+d)'. See e * (d') preferred to (e*d)'. See (e') * d preferred to (e*d)'. $% determine priority rules to avoid ambiguity. For example, the first line indicates that %Pe+d'P% should be parsed as %Pe+(d')P% rather than %P(e+d)'P%.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
And finally the definition of differentiation itself follows. Notice how natural it looks and how painless it is to write. Thanks to the previous four lines we don't need to write surplus brackets. %$ Let n' be 0. Let x' be 1. Let (d + e)' be d' + e'. Let (d * e)' be d' * e + d * e'. Let (e ^ 0)' be 0. Let (e ^ n)' be n * e ^ (n-1) * e'. Close context. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Run it here to see for yourself that it really works. %$ (x*x + x^2)'. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Notice that the derivative is calculated correctly but the resulting expression is unfortunately not simplified. It is exactly as it should be according to the definition of the ' function alone. So we need another function which will simplify expressions. Let us once again introduce temporary variables that we will need in the definitions of the following functions. Notice that we can define such temporary variables in any place in the code and they exist until %PClose context.P% is reached. %$ Variable e as expression. Variable d as expression. Variable n as natural number. Variable m as natural number. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Before we proceed let us define a function to enforce types for the parser. %$ New function expression ''as expression'' as expression. Let e as expression be e. $% This weird function will be used in certain ambiguity-situations to inform the parser that we really need something to be interpreted as having the expression type rather than natural number. Similarly, we will use the as natural number function which is already built into the Speagram library.
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
The following example of usage of type enforcement should be self-explanatory. %$ 1+1. (1 as expression)+(1 as expression). $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
You should now be prepared to study the next function declarations and function definitions on your own. Everything (more or less) means what it says. %$ New function ''basic simplify'' expression as expression. Let basic simplify n be n. Let basic simplify x be x. Let basic simplify (e ^ 0) be 1. Let basic simplify (0 ^ n) be 0. Let basic simplify (1 ^ n) be 1. Let basic simplify (e ^ 1) be basic simplify e. Let basic simplify ((e ^ n) ^ m) be (basic simplify e) ^ (n*m). Let basic simplify (e ^ n) be (basic simplify e) ^ n. Let basic simplify (0 * e) be 0. Let basic simplify (e * 0) be 0. Let basic simplify (1 * e) be basic simplify e. Let basic simplify (e * 1) be basic simplify e. Let basic simplify (e * e) be (basic simplify e) ^ 2. Let basic simplify (e ^ n * e) be (basic simplify e) ^ (n + 1). Let basic simplify (e * e ^ m) be (basic simplify e) ^ (m + 1). Let basic simplify (e ^ n * e ^ m) be (basic simplify e) ^ (n + m). Let basic simplify (n * (m * e)) be (n * m) as natural number * e. Let basic simplify ((n * e) * m) be (n * m) as natural number * e. Let basic simplify (n as expression * m) be (n * m) as natural number. Let basic simplify (0 + e) be basic simplify e. Let basic simplify (e + 0) be basic simplify e. Let basic simplify (e + e) be 2 * basic simplify e. Let basic simplify ((n * e) + e) be (n+1) as natural number * basic simplify e. Let basic simplify (e + (m * e)) be (m+1) as natural number * basic simplify e. Let basic simplify ((n*e) + (m*e)) be (n+m) as natural number * basic simplify e. Let basic simplify (n + (m + e)) be (n + m) as natural number + e. Let basic simplify ((n + e) + m) be (n + m) as natural number + e. Let basic simplify (n as expression + m) be (n + m) as natural number. Let basic simplify ((e * d) * d) be (basic simplify e) * (basic simplify (d*d)). Let basic simplify (e * d) be (basic simplify e) * (basic simplify d). Let basic simplify (e + d) be (basic simplify e) + (basic simplify d). New function ''simplify'' expression as expression. See simplify (e') preferred to (simplify e)'. Let simplify e be if basic simplify e = e then e else simplify (basic simplify e). Close context. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
Try the differentiation and simplification examples for yourself. %$ (2*x^3)'. simplify (2*x^3)'. (x+2*x)'. simplify (x+2*x)'. $%
Done
Hide
Edit
Run
This part
New
Up
Down
Delete
Help
…
''Summary'' We have shown you how to define complex classes and how to write functions. We hope that we have succeeded in convincing you that Speagram's syntax is friendly and makes for readable code that does basically what it says. This brings us to the important point: Speagram is meant to allow the programmer to write such code that it is evident what it does from the way it reads in English — that's why we insist on long descriptive names and allow the syntax of function declarations to be flexible. The power of the Speagram parser has not been fully exploited in this example. We have not really taught the parser that 2x should be understood as 2*x, etc. We do this on a separate page where we discuss [[Extensible Parser Example: Shorthand Notation.php|shorthand notation]], which is a good occasion to reveal the parser's easy extensibility.
Saved XSLT Stylesheet
Saved SRGS Grammar